﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Sunny.Lib
{
    public class ReflectionHelper
    {
        //public static 
        public static Assembly GetAssably(string fullPath)
        {
            Assembly ass = Assembly.LoadFile(fullPath);
            return ass;
        }

        public static Type GetType(string typeName)
        {
            Type type = Type.GetType("", false, true);
            return type;
        }

        public static string GetPropertyValue<T>(T instance, string propertyName)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                Logger.LogEvent("PropertyName" + CommonErrorConstants.NullOrEmpty);
            }

            Type type = instance.GetType();
            string propertyValue = string.Empty;
            System.Reflection.PropertyInfo property = type.GetProperty(propertyName);

            if (property != null)
            {
                propertyValue = property.GetValue(instance, null).ToString();
            }
            else
            {
                Logger.LogEvent(string.Format("Not find the Property by the property name:", propertyName));
            }

            return propertyValue;
        }

        public static void SetPropertyValue<T>(T instance, string propertyName, object propertyValue)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                Logger.LogEvent(CommonErrorConstants.NullOrEmpty);
            }


            Type type = instance.GetType();
            System.Reflection.PropertyInfo property = type.GetProperty(propertyName);

            if (property != null && propertyValue != null)
            {
                type.GetProperty(propertyName).SetValue(instance, ConvertHelper.ChangeType(property.PropertyType, propertyValue), null);
            }
            else
            {
                Logger.LogEvent(string.Format("Not find the Property by the property name:", propertyName));
            }
        }

        public static Dictionary<string, object> GetPropertiesKeyValuePairs<T>(T instance, BindingFlags flags)
        {
            Dictionary<string, object> nameValuePairs = new Dictionary<string, object>();

            if (instance != null)
            {
                Type type = instance.GetType();
                System.Reflection.PropertyInfo[] properties = type.GetProperties(flags);

                foreach (var property in properties)
                {
                    nameValuePairs.Add(property.Name, property.GetValue(instance, null));
                }
            }

            return nameValuePairs;
        }

        public static object CreateModel(Type modelType)
        {
            Type typeToCreate = modelType;

            // we can understand some collection interfaces, e.g. IList<>, IDictionary<,>
            if (modelType.IsGenericType)
            {
                Type genericTypeDefinition = modelType.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(IDictionary<,>))
                {
                    typeToCreate = typeof(Dictionary<,>).MakeGenericType(modelType.GetGenericArguments());
                }
                else if (genericTypeDefinition == typeof(IEnumerable<>)
                    || genericTypeDefinition == typeof(ICollection<>)
                    || genericTypeDefinition == typeof(IList<>))
                {
                    typeToCreate = typeof(List<>).MakeGenericType(modelType.GetGenericArguments());
                }

            }

            return Activator.CreateInstance(typeToCreate);
        }
    }
}
